Tack.ActionBlock = new Class({
	initialize: function (scene) {
		this.actions = [];
		this.conditions = [];
		this.elseBlock = null;

		if (scene) this.setScene(scene);
	},

	addAction: function (action) {
		action.setActionBlock(this);
		this.actions.push(action);
	},

	addCondition: function (condition) {
		condition.setActionBlock(this);
		this.conditions.push(condition);
	},

	changeSceneReferences: function (oldName, newName) {
		this.actions.each(function (a) { a.changeSceneReferences(oldName, newName); });
		this.conditions.each(function (c) { c.changeSceneReferences(oldName, newName); });
		if (this.elseBlock) this.elseBlock.changeSceneReferences(oldName, newName);
	},

	compile: function () {
		var actionBlock = {
			actions: [],
			conditions: [],
			elseBlock: (this.elseBlock ? this.elseBlock.compile() : null)
		};

		this.actions.each(function (action) {
			actionBlock.actions.push(action.compile());
		});

		this.conditions.each(function (condition) {
			actionBlock.conditions.push(condition.compile());
		});

		return actionBlock;
	},

	execute: function (player, eventArgs) {
		if (!player.playing) return;

		for (var i = 0; i < this.conditions.length; i++) {
			if (!this.conditions[i].evaluate(player, eventArgs)) {
				if (this.elseBlock) this.elseBlock.execute(player, eventArgs);
				return;
			}
		}

		for (var i = 0; i < this.actions.length; i++) {
			this.actions[i].execute(player, eventArgs);
			if (!player.playing) return;
		}
	},

	remove: function () {
		if (!this.actionBlock) return;

		if (this == this.actionBlock.elseBlock)
			this.actionBlock.elseBlock = null;
		else
			this.actionBlock.actions.remove(this);
	},

	setElseBlock: function (actionBlock) {
		if (actionBlock == null) {
			this.elseBlock = null;
			return;
		}

		if (!actionBlock instanceof Tack.ActionBlock)
			throw '[actionBlock] must be an instance of Tack.ActionBlock.';

		actionBlock.setActionBlock(this);
		this.elseBlock = actionBlock;
	},

	setActionBlock: function (actionBlock) {
		this.actionBlock = actionBlock;
		this.setScene(actionBlock.scene);
	},

	setScene: function (scene) {
		if (!scene instanceof Tack.Scene)
			throw '[scene] must be an instance of Tack.Scene.';

		if (this.scene == scene) return;

		this.scene = scene;
		if (this.elseBlock) this.elseBlock.setScene(scene);
		this.actions.each(function (a) { a.setActionBlock(this); }, this);
		this.conditions.each(function (c) { c.setActionBlock(this); }, this);
	}
});

Tack.ActionBlock.decompile = function (obj, scene) {
	var ab = new Tack.ActionBlock(scene);

	for (var i = 0; i < obj.actions.length; i++) {
		var a;

		switch ($type(obj.actions[i])) {
			case 'array':
				a = Tack.Action.decompile(obj.actions[i]);
				break;
			case 'object':
				a = Tack.ActionBlock.decompile(obj.actions[i], scene);
				break;
		}
		
		if (a) ab.addAction(a);
	}

	for (var i = 0; i < obj.conditions.length; i++) {
		ab.addCondition(Tack.Condition.decompile(obj.conditions[i]));
	}

	if (obj.elseBlock) {
		ab.setElseBlock(Tack.ActionBlock.decompile(obj.elseBlock, scene));
	}

	return ab;
};
